package org.generic.splash;
import java.io.IOException;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.midlet.MIDlet;

import org.generic.AppCanvas;

/**
 * Splash Class extends a Canvas for exibiting
 * a splash screen with an image in it.
 */
public class Splash extends Canvas {

	private Image image;
	private int   color;
	private int   centerX;
	private int   centerY;
	private Display display;

	private int logoY;
	
	private long startTime;
	private static byte FPS = 13;

	private static int foregrounColor = 0xFFFFFFFF;
	private static int alpha = 			0x04;
	
	/**
	 * Creates a splash screen to display the specified
	 * image and fills the background with the specified
	 * color.
	 * 
	 * @param background
	 */
	public Splash(String image, int background) {
		this.setFullScreenMode(true);
		this.color = background;
		this.logoY = (getWidth() >> 2) + (getWidth() >> 3) ;
		try {
			this.image = Image.createImage(image);
			this.centerX = (this.getWidth() - this.image.getWidth())/2;
			this.centerY = (this.getHeight() - this.image.getHeight())/2;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Shows the splash and changes to the specified
	 * displayable after the specified number of milliseconds.
	 * 
	 * @param display Current Display.
	 * @param next new Displayable.
	 * @param time splash time in milliseconds.
	 */
	 public void show(MIDlet midlet, final AppCanvas next, final long time) {
		display = Display.getDisplay(midlet);
		display.setCurrent(this);
		startTime = System.currentTimeMillis();
		Thread t = new Thread(new Runnable() {
			public void run() {
				try {
					do {
						Thread.sleep(FPS);
						repaint();
						serviceRepaints();
					} while ((startTime + time) > System.currentTimeMillis());
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					next.show();
				}
			}
		});
		t.start();
	}

	protected void paint(Graphics g) {
		g.setColor(this.color);
		g.fillRect(0x00, 0x00, getWidth(), getHeight());
		drawLogo(g);
		drawAlphaRect(g, 0x00, 0x00, getWidth(), getHeight(), foregrounColor, false);
		fadeIn(foregrounColor);
	}
	
	/**
	 * Draws a rect with alpha color.
	 * */
	private static void drawAlphaRect(Graphics g, int x, int y, int width, int height, int color, boolean outline)
    {
        int[] data = new int[width * height];
        for (int i=0; i < data.length; i++)
        {
            data[i] = color;
        }
        g.drawRGB(data, 0, width, x, y, width, height, true);
        
        if (outline)
        {
            int outlineColor = (color & 0x00FFFFFF);
            g.setColor(outlineColor);
            g.drawLine(0, y, width, y);
            g.drawLine(0, y + height, width, y + height);
        }
    }
	
	private void drawLogo(Graphics g) {
		if (logoY < this.centerY) {
			logoY++;
		}
		if (this.image != null) {
			g.drawImage(this.image, this.centerX, logoY, 0x00);
		}
	}
	
	/**
	 * Fades the color passed as parameter.
	 * @param argbColor The color to be faded.
	 * */
	private void fadeIn(int argbColor) {
		int _alpha = alpha << 24;
		foregrounColor -= _alpha;
	}
}
